package org.displayextended
{
	import flash.events.Event;
	import flash.events.MouseEvent;
	
	/**
	 * MovieSprite Button
	 * 
	 * This class provides basic Button functionality to an asset or stage instance movieclip 
	 * 
	 * Can use an external asset OR stage instance
	 * The movieclip must have labels for mouse over, out and press
	 * Optionally labels can be set for animated build ins and outs, since this class extends AnimatedMovieSprite
	 *
	 * This class should be extended for more advanced functionlity or to encapsulate custom label Constants, etc...
	 * 
	 * See AnimateMovieSprite for details on animated build in/out
	 * 
	 * Usage:
	 * 
	 * 1) Initialize Class with Asset OR Stage Instance:
	 * 
	 * 	var button:MovieSpriteButton = new MovieSpriteButton( 'path.to.some.asset'[ OR  somechildmc.button ] );
	 * 	
	 * 	addChild( button ); <- only if using external asset (no need to addChild of instance since it is already on stage)
	 * 
	 * 2) Set properties if need be, (labels, etc) defaults work fine & should be used where possible
	 * 	
	 * 	button.animateBuild = false;
	 * 	button.defaultLabel = 'someLabel';
	 *
	 * 3) Add listeners in parent class for clicks and buildCompletes
	 * 
	 * 	button.addEventListener( MouseEvent.CLICK, onButtonPress );
	 * 	button.addEventListener( BuildCompleteEvent.ANUMIATE_IN_COMPLETE, onButtonAnimateInComplete );
	 * 
	 * 4) Display it (whether animated or not)
	 * 
	 * 	button.buildIn();
	 * 
	 * @author zachary.seabrook
	*/
	public class MovSpriteButton extends AniMovSprite
	{
		public static var DEFAULT_DISABLED_LABEL:String = 'default';
		public static var DEFAULT_MOUSE_OVER_LABEL:String = 'mouseOver';
		public static var DEFAULT_MOUSE_OUT_LABEL:String = 'mouseOut';
		public static var DEFAULT_MOUSE_PRESS_LABEL:String = 'mousePress';
		
		private var _disabledLabel:String;
		private var _mouseOverLabel:String;
		private var _mouseOutLabel:String;
		private var _mousePressLabel:String;
		
		private var buildingOut:Boolean;
		
		public function MovSpriteButton( movieClipClassPathOrInstance:Object=null )
		{
			// turn tracing off by default
			showTrace = false;
			
			super( movieClipClassPathOrInstance );
		}
		
		override public function buildOut():void
		{
			t( '[MovSpriteButton] buildOut' );
			
			buildingOut = true;
			
			removeEventListeners();
			
			if( animateBuild )
			{
				gotoAndPlay( buildOutLabel );
				startFrameMonitoring();
			}
			else
			{
				onBuildOutComplete();
			}
		}
		
		override protected function doFrameMonitor( event:Event ):void
		{
			//t( '[AniMovSprite] doFrameMonitor', currentFrame, totalFrames, currentLabel, defaultLabel );
			
			if( buildingOut && currentLabel != buildOutLabel )
				gotoAndPlay( buildOutLabel );
			
			if( currentFrame == totalFrames )
			{
				onBuildOutComplete()
				endFrameMonitoring();
			}
			
			if( currentLabel == defaultLabel )
			{
				onBuildInComplete();
				endFrameMonitoring();
			}
		}
		
		override public function buildIn():void
		{
			buildingOut = false;
			
			tabEnabled = false;
			visible = true;
			
			if( enabled )
			{
				setButtonViewEnabled();
				addEventListeners();
			}
			else
			{
				setButtonViewDisabled();
				removeEventListeners();
			}
		}
		
		public function setButtonViewDisabled( transition:Boolean=false ):void
		{
			mouseChildren = false;
			useHandCursor = false;
			buttonMode = false;
			gotoAndStop( disabledLabel );
		}
		
		public function setButtonViewEnabled( transition:Boolean=false ):void
		{
			mouseChildren = true;
			useHandCursor = true;
			buttonMode = true;
			
			if( animateBuild )
			{
				gotoAndPlay( buildInLabel );
				startFrameMonitoring();
			}
			else
			{
				gotoAndStop( defaultLabel );
				onBuildInComplete();
			}
		}
		
		override public function set enabled( value:Boolean ):void
		{
			t( 'enabled', value );
			
			mc.enabled = value;
			
			if( value )
			{
				setButtonViewEnabled();
				addEventListeners();
			}
			else
			{
				setButtonViewDisabled();
				removeEventListeners();
			}
		}
		
		override public function get enabled():Boolean
		{
			return mc.enabled;
		}
		
		// Internal Event Listening
		
		public function addEventListeners():void
		{
			addEventListener( MouseEvent.MOUSE_OVER, onMouseOver );
			addEventListener( MouseEvent.MOUSE_OUT, onMouseOut );
			addEventListener( MouseEvent.CLICK, onMousePress );
		}
		
		public function removeEventListeners():void
		{
			removeEventListener( MouseEvent.MOUSE_OVER, onMouseOver );
			removeEventListener( MouseEvent.MOUSE_OUT, onMouseOut );
			removeEventListener( MouseEvent.CLICK, onMousePress );
		}
		
		public function onMouseOver( event:MouseEvent ):void
		{
			gotoAndPlay( mouseOverLabel );
			
		}
		
		public function onMouseOut( event:MouseEvent ):void
		{
			gotoAndPlay( mouseOutLabel );
		}
		
		public function onMousePress( event:MouseEvent ):void
		{
			gotoAndPlay( mousePressLabel );
		}
		
		// Property Getter/Setters
		
		public function get mouseOverLabel():String
		{
			if( !_mouseOverLabel )
				_mouseOverLabel = DEFAULT_MOUSE_OVER_LABEL;
			
			return _mouseOverLabel;
		}
		
		public function set mouseOverLabel( val:String ):void
		{
			_mouseOverLabel = val;
		}
		
		public function get mouseOutLabel():String
		{
			if( !_mouseOutLabel )
				_mouseOutLabel = DEFAULT_MOUSE_OUT_LABEL;
			
			return _mouseOutLabel;
		}
		
		public function set mouseOutLabel( val:String ):void
		{
			_mouseOutLabel = val;
		}
		
		public function get mousePressLabel():String
		{
			if( !_mousePressLabel )
				_mousePressLabel = DEFAULT_MOUSE_PRESS_LABEL;
			
			return _mousePressLabel;
		}
		
		public function set mousePressLabel( val:String ):void
		{
			_mousePressLabel = val;
		}
		
		public function get disabledLabel():String
		{
			if( !_disabledLabel )
				_disabledLabel = DEFAULT_DISABLED_LABEL;
			
			return _disabledLabel;
		}
		
		public function set disabledLabel( val:String ):void
		{
			_disabledLabel = val;
		}
	}
}